package com.wangzhixuan.commons.base;

import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wangzhixuan.commons.result.PageInfo;
import com.wangzhixuan.commons.result.Result;
import com.wangzhixuan.commons.utils.Charsets;
import com.wangzhixuan.commons.utils.StringEscapeEditor;
import com.wangzhixuan.commons.utils.URLUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.util.List;
import java.util.Objects;

public abstract class BaseController {
    protected Logger logger = LogManager.getLogger(getClass());
    @Value("${domain:}")
    private String domain;
    @Autowired
    protected HttpServletRequest request;

    @InitBinder
    public void initBinder(ServletRequestDataBinder binder) {
        /**
         * 防止XSS攻击
         */
        binder.registerCustomEditor(String.class, new StringEscapeEditor());
    }

    /**
     * 获取域名
     *
     * @return 访问域名地址
     */
    protected String getDomain() {
        return StringUtils.isNotBlank(domain) ? domain : request.getRequestURL().substring(0, request.getRequestURL().indexOf(request.getServletPath()));
    }

    /**
     * ajax失败
     *
     * @param msg 失败的消息
     * @return {Object}
     */
    public <T> Result<T> renderError(String msg) {
        Result<T> result = new Result<>();
        result.setMsg(msg);
        result.setCode(9);
        return result;
    }

    /**
     * ajax成功
     *
     * @return {Object}
     */
    public <T> Result<T> renderSuccess() {
        Result<T> result = new Result<>();
        result.setSuccess(true);
        return result;
    }

    /**
     * ajax成功
     *
     * @param msg 消息
     * @return {Object}
     */
    public Result<String> renderSuccess(String msg) {
        Result<String> result = new Result<>();
        result.setSuccess(true);
        result.setMsg(msg);
        return result;
    }

    /**
     * ajax成功
     *
     * @param obj 成功时的对象
     * @return {Object}
     */
    public <T> Result<T> renderObj(T obj) {
        Result<T> result = new Result<>();
        result.setSuccess(true);
        result.setObj(obj);
        return result;
    }

    public <T> Page<T> getPage(int current, int size, List<OrderItem> orderItems) {
        Page<T> page = new Page<T>(current, size);
        page.setOrders(orderItems);
        return page;
    }

    public <T> PageInfo<T> pageToPageInfo(Page<T> page) {
        PageInfo<T> pageInfo = new PageInfo<>();
        pageInfo.setRows(page.getRecords());
        pageInfo.setTotal(page.getTotal());
        pageInfo.setOrder(page.getOrders().get(0).getColumn());
        return pageInfo;
    }

    /**
     * 下载文件
     *
     * @param file 文件
     */
    protected ResponseEntity<Resource> download(File file) {
        String fileName = file.getName();
        return download(file, fileName);
    }

    /**
     * 下载
     *
     * @param file     文件
     * @param fileName 生成的文件名
     * @return {ResponseEntity}
     */
    protected ResponseEntity<Resource> download(File file, String fileName) {
        Resource resource = new FileSystemResource(file);

        HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder
                .getRequestAttributes())).getRequest();
        String header = request.getHeader("User-Agent");
        // 避免空指针
        header = header == null ? "" : header.toUpperCase();
        HttpStatus status;
        if (header.contains("MSIE") || header.contains("TRIDENT") || header.contains("EDGE")) {
            fileName = URLUtils.encodeURL(fileName, Charsets.UTF_8);
            status = HttpStatus.OK;
        } else {
            fileName = new String(fileName.getBytes(Charsets.UTF_8), Charsets.ISO_8859_1);
            status = HttpStatus.CREATED;
        }
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        headers.setContentDispositionFormData("attachment", fileName);
        return new ResponseEntity<Resource>(resource, headers, status);
    }
}
